package com.tengyun.middleplatform.trade.tradedata.config;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.module.SimpleModule;

import org.linuxprobe.luava.json.jackson.deserializer.JsonBooleanDeserializer;
import org.linuxprobe.luava.json.jackson.deserializer.JsonDateDeserializer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.task.TaskExecutor;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.concurrent.ThreadPoolExecutor;

@Configuration
public class SpringConfiguration {


	/**
	 * 配置该bean可以在@Configuration注解的类里面使用@Value注解
	 */
	@Bean
	public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
		return new PropertySourcesPlaceholderConfigurer();
	}

	/**
	 * 定义异步任务的线程池
	 *
	 * @return
	 */
	@Bean
	public TaskExecutor taskExecutor() {
		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
		// 设置核心线程数
		executor.setCorePoolSize(5);
		// 设置最大线程数
		executor.setMaxPoolSize(10);
		// 设置队列容量
		executor.setQueueCapacity(20);
		// 设置线程活跃时间（秒）
		executor.setKeepAliveSeconds(60);
		// 设置默认线程名称
		executor.setThreadNamePrefix("trade-data-");
		// 设置拒绝策略
		executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
		// 等待所有任务结束后再关闭线程池
		executor.setWaitForTasksToCompleteOnShutdown(true);
		return executor;
	}


	@Bean
	@Primary
	public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
		ObjectMapper objectMapper = builder.createXmlMapper(false).build();

		// 通过该方法对mapper对象进行设置，所有序列化的对象都将按改规则进行系列化
		// Include.Include.ALWAYS 默认
		// Include.NON_DEFAULT 属性为默认值不序列化
		// Include.NON_EMPTY 属性为 空（""） 或者为 NULL 都不序列化，则返回的json是没有这个字段的。这样对移动端会更省流量
		// Include.NON_NULL 属性为NULL 不序列化
		objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
		objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
		// 允许出现特殊字符和转义符
		objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
		// 允许出现单引号
		objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);

		SimpleModule simpleModule = new SimpleModule();
		simpleModule.addDeserializer(Date.class, JsonDateDeserializer.getInstance());
		simpleModule.addDeserializer(Boolean.class, JsonBooleanDeserializer.getInstance());
		simpleModule.addDeserializer(LocalDate.class, JsonLocalDateFormatter.buildDeserializer());
		simpleModule.addSerializer(LocalDate.class, JsonLocalDateFormatter.buildSerializer());
		simpleModule.addDeserializer(LocalDateTime.class, JsonLocalDateTimeFormatter.buildDeserializer());
		simpleModule.addSerializer(LocalDateTime.class, JsonLocalDateTimeFormatter.buildSerializer());
		simpleModule.addDeserializer(Long.class, JsonLongFormatter.buildDeserializer());
		simpleModule.addSerializer(Long.class, JsonLongFormatter.buildSerializer());

		// 注册自定义反序列化, 适用于json传递参数
		objectMapper.registerModule(simpleModule);
		objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);//驼峰统一返回下划线

		return objectMapper;
	}
}
